package it.omnisong.server.index;

import it.omnisong.client.model.Wikilink;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.queryParser.ParseException;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.QueryTermVector;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopScoreDocCollector;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;
import org.junit.Test;

public class WikipediaSearcher {

	private IndexSearcher searcher;
	private Analyzer analyzer;
	TopScoreDocCollector collector = TopScoreDocCollector.create(5, true);
	private ArrayList<Wikilink> resultDocs;
	private String indexDir = "omnisonggwt/index/wikipedia";
	
	/* costruttore no-argument */
	public WikipediaSearcher() throws IOException {
		FSDirectory dir = FSDirectory.open(new File(this.indexDir));
		this.searcher = new IndexSearcher(dir, true);
		this.analyzer = new StandardAnalyzer(Version.LUCENE_30);
	}

	/* metodo che ricerca nell'indice con la query passata come parametro */
	public ArrayList<Wikilink> searchIndex(String queryString) throws ParseException, IOException {
		// Parse a simple query that searches for "text":
		this.resultDocs = new ArrayList<Wikilink>();
	    QueryParser parser = new QueryParser(Version.LUCENE_30, "name", analyzer);
	    parser.setDefaultOperator(QueryParser.Operator.AND);
	    parser.setFuzzyMinSim((float) 0.6);
	    queryString = fuzzyQuery(queryString); // modifico la query per ottenere una ricerca fuzzy
	    Query query = parser.parse(queryString);
	    System.out.println(query.toString());
	    this.searcher.search(query, collector);
	    ScoreDoc[] hits = collector.topDocs().scoreDocs;
	    // Iterate through the results:
	    for (int i = 0; i < hits.length; i++) {
	      Document hitDoc = this.searcher.doc(hits[i].doc);
	      String name = hitDoc.get("name");
	      String url = hitDoc.get("url");
	      this.resultDocs.add(new Wikilink(name, url));
	    }
	    this.closeSearcher();
	    return this.resultDocs;
	}
	
	/* metodo che chiude il searcher */
	public void closeSearcher() throws IOException {
	    this.searcher.close();
	}
	
	/* metodo che modifica la query per crearne una fuzzy */
	private String fuzzyQuery(String queryString) {

	    QueryTermVector termVector = new QueryTermVector(queryString, this.analyzer);
	    String[] terms = termVector.getTerms();
	    String queryResult = "";
	    for(String term : terms) {
	    	term = term.concat("~");
	    	queryResult = queryResult.concat(term+" ");
	    }
	    
		return queryResult;
		
	}
	
	/* test di indicizzazione */
	@Test
	public void index() {
		try {
			List<Wikilink> result = searchIndex("beatles");
			for (Wikilink r : result) {
				System.out.println(r.getUrl());
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
